#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <iostream>
#include <linux/if_ether.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include "definitions.hpp"

using namespace std;

#define SIZE_ETHERNET 14

string dest_mac;
list<string> interface_list;		



// Parse ARP Begin //

void parse_arp(){
	char buffer[4000];
	FILE *fp = fopen("/proc/net/arp","r");
	if(fp == NULL){
		cerr<<"Error in opening file! Please try again\n";
		//exit(1);
	}
        bzero(buffer,4000);
	int loop_counter = 0;
	while(fgets(buffer,4000,fp)!=NULL){
	loop_counter++;
		if(loop_counter == 1){
			continue;
		}else{
			//Parse buffer here
			int inner_loop = 0;
			char *pch;
			pch = strtok (buffer," ");
			string ipadd;
  			while (pch != NULL)
  			{
				inner_loop++;

				if(inner_loop == 1) // Parse for IPAddress, making the last 8 Bits zero
				{	ipadd.clear();
					ipadd = string(pch);
					//ipadd[ipadd.length()-1] = '0';
				}

				if(inner_loop == 4)
				{
					string macadd = string(pch);


					pch = strtok (NULL," ");
					pch = strtok (NULL," ");

					string inter = string(pch);
					inter = inter.substr(0,inter.length()-1);
					//push to interface list
					//interface_list.push_back(inter);
					string ipadd_tmp;
					ipadd_tmp.clear();
					ipadd_tmp = ipadd.substr(0,4);
					if(ipadd_tmp.compare("10.1") == 0){
                        interface_list.push_back(inter);
						cout<<"macadd is "<<macadd<<endl;
						dest_mac = macadd;		
                            
					}else;

					break;
				}
			       pch = strtok (NULL, " ");
 		        }
		}

	bzero(buffer,4000);

	}

}

// Parse ARP End //


int main(int argc, char** argv){

    // Begin Parsing //

	parse_arp();

	// End Parsing //

	string filename = string(argv[1]);

	FILE *fp = fopen(filename.c_str(),"rb");

	struct ethhdr *eth_hdr = (ethhdr*)malloc(ETH_HLEN);

	unsigned char* packet_buf = (unsigned char* )malloc(66);



	int sock_eth;

	 if ((sock_eth = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
        perror("socket-eth-rdwr");
        exit(1);
    }


	   struct sockaddr_ll sll;
	   struct ifreq ifr;

	   bzero(&sll, sizeof(sll));
	   bzero(&ifr, sizeof(ifr));
	   char* dev = (char *)interface_list.front().c_str();
	   /* First Get the Interface Index  */
	   strncpy((char *)ifr.ifr_name, (const char*)dev, IFNAMSIZ);
	   if((ioctl(sock_eth, SIOCGIFINDEX, &ifr)) == -1)
	   {
	   printf("Error getting Interface index !\n");
	   exit(-1);
	   }

	   /* Bind our raw socket to this interface */

	   sll.sll_family = AF_PACKET;
	   sll.sll_ifindex = ifr.ifr_ifindex;
	   //sll.sll_protocol = htons(ETH_P_ALL);

	   if((bind(sock_eth, (struct sockaddr *)&sll, sizeof(sll)))== -1)
	   {
	   perror("Error binding raw socket to interface\n");
	   exit(-1);
       }
      
	  string src_mac("00:00:00:00:00:00");;
    memcpy(eth_hdr->h_source, (void *)(ether_aton(src_mac.c_str())), ETH_ALEN);
	memcpy(eth_hdr->h_dest, (void *)(ether_aton(dest_mac.c_str())), ETH_ALEN);

	memcpy(&packet_buf[0],&eth_hdr,14);

    //uint16_t size = 50;

	
 while(!feof(fp)){

	 bzero(&packet_buf[14],52);

	 uint16_t fr = fread(&packet_buf[16],1,50,fp);

	 cout<<" Size on Server "<<fr <<endl;

	 memcpy(&packet_buf[14],&fr,2);
	 
	
// Write into a raw socket
    cout<<"writing into dev" <<dev<<endl;

	int r;

     r = write(sock_eth, packet_buf, 66);
     if(r <0) {
		 perror("sendto-if");
	 }
	 cout<<"Bytes Sent on if R "<<r<<endl;


 //free(buf);

}// while(1)

fclose(fp);
return 0;
}//rdwr function



